<?php
/**
 * Created by PhpStorm
 * User: shen.zk
 * Date: 2023/9/4
 * Time: 17:37
 * Comment: '签名验证中间件'
 */

namespace App\Http\Middleware;

use App\Common\Constant;
use App\Service\Common\CheckSignService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;
use Closure;
use Illuminate\Support\Facades\Redis;
use App\Repository\MerchantsInfoRepo;

class DataSignMiddleware
{
    public function handle(Request $request, Closure $next)
    {
        $secretData = $request->input();

        Log::info("[中间件]验签中间件打印请求参数" . json_encode($secretData,JSON_UNESCAPED_UNICODE));

        $err = ['error_code'=>2,"error_msg" => "验签中间件-请求参数不能为空",'data'=>'','sign'=>'','encryptKey'=>'','timestamp'=>time()];
        if(empty($secretData))
            return response()->json($err);

        $merchantsInfo = Cache::get(Constant::MERCHANTID.':'.$secretData['access_mid']);
        Log::info("[中间件]商户信息打印" .$merchantsInfo);
        if (empty($merchantsInfo))
        {
            $err['error_msg'] = '商户信息不能为空';
            return response()->json($err);
        }


        $info = json_decode($merchantsInfo,true);

        try {
            // 签名验证
            CheckSignService::getInstance()->verifySign($secretData['data'],$secretData['sign'],$info['public_key']);

            // 获取AES-KEY
            $privateKeyPath = config('selfpem.self_private');

            $privateKey = file_get_contents($privateKeyPath);
            $aeskey = CheckSignService::getInstance()->decryptByPri($secretData['encryptKey'],$privateKey);

            $response = CheckSignService::getInstance()->aesDecrypt($secretData['data'],$aeskey);
            Log::info("[中间件]打印解密报文".$response);

            $responseArr = json_decode($response,true);

            // 平台模式下需要校验商户号和平台号的对应关系
            if ($secretData['access_mode'] == 'platform' && isset($responseArr['mid'])) {
                $platform = MerchantsInfoRepo::getInstance()->getPlatformByAccessMid($responseArr['mid']);
                if (!$platform || $secretData['access_mid'] != $platform['platform_no']) {
                    $err['error_msg'] = '平台模式商户号异常';
                    return response()->json($err);
                }
            }

            // 反向写入请求
            foreach ($responseArr as $key=>&$value)
            {
                // 去掉请求体内的商户号，防止绕过签名操作其它商户内的藏品
                if ($key == 'access_mid')
                    unset($responseArr[$key]);

                $request->offsetSet($key,$value);
            }

            return $next($request);
        } catch (\Exception $e) {
            Log::info("[中间件]处理信息异常".$e->getMessage());
            $err['error_msg'] = $e->getMessage();
            return response()->json($err);
        }

    }
}
